home *** CD-ROM | disk | FTP | other *** search
- /* editgets.c - line input w/editing */
- /* this code is released to the public domain */
- /* written by Jon Burchmore */
- /* modifications & enhancements by Bob Stout */
-
- /* This is as close to ANSI compliant C that I could come, but it was made */
- /* on an IBM compatable computer, so I designed it for that platform. */
- /* If you're porting it to another computer type, please note how the IBM */
- /* passes enhanced keys. First, it sends an ASCIIZ (character 0), then a */
- /* standard character. Anyway, what the switch() statement does is check */
- /* to see if there WAS a zero sent, and if there wasn't, it just "falls" */
- /* through to the default, which handles normal characters. */
-
- /* The conio header file provides the getch() function, which returns a */
- /* single character from the KEYBOARD, not stdin, and waits if it must. */
- /* It is be possible to re-write this function for a computer besides an */
- /* IBM PC. */
-
- /* It would be possible to check the variable insert, and if it's on, make */
- /* the cursor large, and if it's off, make the cursor small, but my primary */
- /* goal is portability, not fancy add-ons */
-
- /* Pardon the lack of comments. I'm a coder, not an author. Besides, if */
- /* you can't understand this, DON'T USE IT! (Words to live by) */
-
- #include <conio.h>
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
-
- #undef min
- #define min(x,y) (((x) <= (y)) ? (x) : (y))
-
- #define NUL 0x00
- #define ESC 0x1B
- #define LEFT 0x4B
- #define RIGHT 0x4D
- #define HOME 0x47
- #define END 0x4F
- #define INSERT 0x52
- #define DELETE 0x53
- #define BACKSPC 0x08
- #define ENTER 0x0D
- #define CTLEND 0x75
- #define CTLHOME 0x77
- #define CTLRT 0x74
- #define CTLLFT 0x73
-
- /*
- ** Password mode - '*' is echoed for all characters, only ESC, ENTER,
- ** BACKSPC, and CTLHOME are active.
- */
-
- int password_mode = 0;
-
- /*
- ** Aruments: 1) Buffer to receive string
- ** 2) Size of buffer
- ** 3) Default string
- */
-
- int jgets(char *s, int maxlen, char *string)
- {
- char temp[500];
- int insert = 1, done = 0, pos, len, i, j, c, zeroflag;
-
- if (NULL == string)
- string = "";
-
- if (0 != (pos = len = strlen(string)))
- strncpy(temp, string, min(len, maxlen));
-
- for (i = 0; i < maxlen; ++i)
- {
- if (NUL == *string)
- putchar('_');
- else putchar(*string++);
- }
- for (i = 0; i < (maxlen - len); ++i)
- putchar(BACKSPC);
-
- while (!done)
- {
- zeroflag = 0;
- if ((c = getch()) == 0)
- {
- zeroflag = 1;
- c = getch();
- }
- switch (c)
- {
- case ESC :
- if (len == 0)
- break;
- if (pos != len)
- {
- for (i = pos; i < len; i++)
- putch('_');
- for (i = len; i >= 0; i--)
- {
- putch(BACKSPC);
- putch('_');
- putch(BACKSPC);
- }
- pos = len = 0;
- break;
- }
-
- case LEFT :
- if (zeroflag)
- {
- if (password_mode)
- break;
- if (pos == 0)
- break;
- pos--;
- putch(BACKSPC);
- break;
- }
-
- case RIGHT :
- if (zeroflag)
- {
- if (password_mode)
- break;
- if (pos == len)
- break;
- if (pos != maxlen)
- {
- putch(temp[pos]);
- pos++;
- }
- break;
- }
-
- case HOME :
- if (zeroflag)
- {
- if (password_mode)
- break;
- while (pos-- > 0)
- putch(BACKSPC);
- pos = 0;
- break;
- }
-
- case END :
- if (zeroflag)
- {
- if (password_mode)
- break;
- while (pos < len)
- putch(temp[pos++]);
- break;
- }
-
- case INSERT :
- if (zeroflag)
- {
- if (password_mode)
- break;
- insert = (!(insert));
- break;
- }
-
- case DELETE :
- if (zeroflag)
- {
- if (password_mode)
- break;
- if (pos == len)
- break;
- for (i = pos; i < len; i++)
- temp[i] = temp[i + 1];
- len--;
- for (i = pos; i < len; i++)
- putch(temp[i]);
- putch('_');
- for (i = len + 1; i > pos; i--)
- putch(BACKSPC);
- break;
- }
-
- case BACKSPC :
- if (c == BACKSPC)
- {
- if (pos == 0)
- break;
- if (pos != len)
- {
- for (i = pos - 1; i < len; i++)
- temp[i] = temp[i + 1];
- pos--;
- len--;
- putch(BACKSPC);
- for (i = pos; i < len; i++)
- putch(temp[i]);
- putch('_');
- for (i = len; i >= pos; i--)
- putch(BACKSPC);
- }
- else
- {
- putch(BACKSPC);
- putch('_');
- putch(BACKSPC);
- pos = --len;
- }
- break;
- }
-
- case ENTER :
- if (c == ENTER)
- {
- done = 1;
- break;
- }
-
- case CTLEND :
- if (zeroflag)
- {
- if (password_mode)
- break;
- for (i = pos; i < len; ++i)
- putch('_');
- for (i = pos; i < len; ++i)
- putch(BACKSPC);
- len = pos;
- break;
- }
-
- case CTLHOME :
- if (zeroflag)
- {
- if (pos == 0)
- break;
- if (pos != len)
- {
- while (0 != pos)
- {
- for (i = pos - 1; i < len; i++)
- temp[i] = temp[i + 1];
- pos--;
- len--;
- putch(BACKSPC);
- for (i = pos; i < len; i++)
- putch(temp[i]);
- putch('_');
- for (i = len; i >= pos; i--)
- putch(BACKSPC);
- }
- }
- else
- {
- while (0 != pos)
- {
- putch(BACKSPC);
- putch('_');
- putch(BACKSPC);
- pos = --len;
- }
- }
- break;
- }
-
- case CTLRT :
- if (zeroflag)
- {
- if (password_mode)
- break;
- do
- {
- if (pos == len)
- break;
- if (pos != maxlen)
- {
- putch(temp[pos]);
- pos++;
- }
- } while (isspace(temp[pos]));
- do
- {
- if (pos == len)
- break;
- if (pos != maxlen)
- {
- putch(temp[pos]);
- pos++;
- }
- } while (!isspace(temp[pos]));
- break;
- }
-
- case CTLLFT :
- if (zeroflag)
- {
- if (password_mode)
- break;
- do
- {
- if (pos == 0)
- break;
- pos--;
- putch(BACKSPC);
- } while (isspace(temp[pos]));
- do
- {
- if (pos == 0)
- break;
- pos--;
- putch(BACKSPC);
- } while (!isspace(temp[pos]));
- break;
- }
-
- default :
- if (zeroflag)
- break;
- if (c == 0 || pos == maxlen)
- break;
- if ((!(insert)) || pos == len)
- {
- temp[pos++] = (char)c;
- if (pos > len) len++;
- if (password_mode)
- putch('*');
- else putch(c);
- }
- else
- {
- if (len == maxlen)
- break;
- for (i = len++; i >= pos; i--)
- temp[i + 1] = temp[i];
- temp[pos++] = (char)c;
- if (password_mode)
- putch('*');
- else putch(c);
- for (i = pos; i < len; i++)
- putch(temp[i]);
- for (i = len; i > pos; i--)
- putch(BACKSPC);
- }
- }
- }
- temp[len] = '\0';
- strcpy(s, temp);
- return len;
- }
-
- #ifdef TEST
-
- main()
- {
- char mystring[60];
-
- memset(mystring, 0, 60);
- fputs("Enter any string: ", stdout);
- jgets(mystring, 60, "This is a test");
- puts("");
- printf("editgets() returned:\n%s\n", mystring);
-
- password_mode = 1;
- memset(mystring, 0, 60);
- fputs("Enter any password: ", stdout);
- jgets(mystring, 50, NULL);
- puts("");
- printf("editgets() returned:\n%s\n", mystring);
- return 0;
- }
-
- #endif
-